package cn.com.libertymutual.core.email;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;

import javax.annotation.PostConstruct;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.InputStreamSource;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;
import org.springframework.util.Base64Utils;

import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

@Component
public class EmailServiceImpl implements IEmailService {
	private  Logger log = LoggerFactory.getLogger(getClass());
	
	@Autowired  
	private JavaMailSender mailSender;
	 
	private EmailEntity  emailEntity =null;
	
	//邮件内容编码，防止乱码  
    private static String charset="UTF-8";
    
    public void init() {
    	
    }
    
    public void destroy() {
    	
    }
    
    @PostConstruct
	@ConfigurationProperties(prefix="spring.mail")
	public EmailEntity emailSource() {
		
		log.info("email servic init...");
		
		this.emailEntity = new EmailEntity();
    	
    	//emailEntity.setPassword( new String( Base64Utils.decodeFromString( emailEntity.getPassword()) ) );
    	
		return this.emailEntity;
	}
	
    private boolean send(String subject, String content,
    		List<String> toEmils, List<String> ccEmails,
    		List<String> bccEmails ,Map<String,InputStreamSource > attachments , boolean html) throws MessagingException , UnsupportedEncodingException {
    	
    	if(attachments==null || attachments.isEmpty()){
    		emailEntity.setMultipart(false);
    	}else{
    		emailEntity.setMultipart(true);
    		
    	}
    	
    	//JavaMailSenderImpl senderImpl = new JavaMailSenderImpl();  
		
		// 设定mail server  
        ///senderImpl.setHost(emailEntity.getSmtpHost());
        // 建立邮件消息,发送简单邮件和html邮件的区别  
        MimeMessage mailMessage = mailSender.createMimeMessage();  
        // 注意这里的boolean,等于真的时候才能嵌套图片，在构建MimeMessageHelper时候，所给定的值是true表示启用，  
        // multipart模式 为true时发送附件 可以设置html格式  
        MimeMessageHelper messageHelper = new MimeMessageHelper(mailMessage, emailEntity.isMultipart(), charset);  
        
        // 设置收件人，寄件人  
        if( toEmils != null ) {
        	for (String tomail : toEmils) {
        		messageHelper.addTo(tomail);
			}
        	//messageHelper.setTo("toMail@sina.com");
        }

        if( Strings.isNullOrEmpty( emailEntity.getDisplayFromUserName() ))
        	messageHelper.setFrom(emailEntity.getFromEmail());
        else messageHelper.setFrom(emailEntity.getFromEmail(), emailEntity.getDisplayFromUserName());
        
        //抄送
        if( ccEmails != null ) {
        	for (String ccmail : ccEmails) {
        		messageHelper.addCc(ccmail);
			}
        }
        
        //秘密抄送
        if( bccEmails != null ) {
        	for (String bccmail : bccEmails) {
        		messageHelper.addBcc(bccmail);
			}
        }
        
        
        messageHelper.setSubject( subject );
        
        // true 表示启动HTML格式的邮件  
        messageHelper.setText( content, html );  
        if( attachments!=null && !attachments.isEmpty()){
	        Iterator<Entry<String, InputStreamSource>> it = attachments.entrySet().iterator();
	        while (it.hasNext()){
	        	Entry<String, InputStreamSource> e = it.next();
	        	messageHelper.addAttachment( e.getKey(), e.getValue());
	        }
        	
        }
        /*if( emailEntity.isAuth()) {
	        senderImpl.setUsername( emailEntity.getUsername() ); // 根据自己的情况,设置username  
	        log.info("emailEntity:{}", emailEntity); 
	        senderImpl.setPassword( emailEntity.getPassword()); // 根据自己的情况, 设置password
        }*/
        
        Properties prop = new Properties();  
        prop.put("mail.smtp.auth", emailEntity.isAuth()); // 将这个参数设为true，让服务器进行认证,认证用户名和密码是否正确  
        prop.put("mail.smtp.timeout", emailEntity.getTimeout() );   
        
        ///senderImpl.setJavaMailProperties(prop);  
        // 发送邮件  
        
        ///senderImpl.testConnection();
        
        mailSender.send(mailMessage);  
        ///senderImpl.send( new EmailMessagePreparator() );
        
        log.info(subject+" 邮件发送成功...");
		
		return true;
    	
    	
    	
    }
    
    @Deprecated
    private boolean send2(String subject, String content,
    		List<String> toEmils, List<String> ccEmails,
    		List<String> bccEmails ,Map<String,InputStreamSource > attachments , boolean html) throws MessagingException , UnsupportedEncodingException {
    	if(attachments==null || attachments.isEmpty()){
    		emailEntity.setMultipart(false);
    	}else{
    		emailEntity.setMultipart(true);
    		
    	}
    	JavaMailSenderImpl senderImpl = new JavaMailSenderImpl();  
		
		// 设定mail server  
        senderImpl.setHost(emailEntity.getSmtpHost());
        // 建立邮件消息,发送简单邮件和html邮件的区别  
        MimeMessage mailMessage = senderImpl.createMimeMessage();  
        // 注意这里的boolean,等于真的时候才能嵌套图片，在构建MimeMessageHelper时候，所给定的值是true表示启用，  
        // multipart模式 为true时发送附件 可以设置html格式  
        MimeMessageHelper messageHelper = new MimeMessageHelper(mailMessage, emailEntity.isMultipart(), charset);  
        
        // 设置收件人，寄件人  
        if( toEmils != null ) {
        	for (String tomail : toEmils) {
        		messageHelper.addTo(tomail);
			}
        	//messageHelper.setTo("toMail@sina.com");
        }

        if( Strings.isNullOrEmpty( emailEntity.getDisplayFromUserName() ))
        	messageHelper.setFrom(emailEntity.getFromEmail());
        else messageHelper.setFrom(emailEntity.getFromEmail(), emailEntity.getDisplayFromUserName());
        
        //抄送
        if( ccEmails != null ) {
        	for (String ccmail : ccEmails) {
        		messageHelper.addCc(ccmail);
			}
        }
        
        //秘密抄送
        if( bccEmails != null ) {
        	for (String bccmail : bccEmails) {
        		messageHelper.addBcc(bccmail);
			}
        }
        
        
        messageHelper.setSubject( subject );
        
        // true 表示启动HTML格式的邮件  
        messageHelper.setText( content, html );  
        if( attachments!=null && !attachments.isEmpty()){
	        Iterator<Entry<String, InputStreamSource>> it = attachments.entrySet().iterator();
	        while (it.hasNext()){
	        	Entry<String, InputStreamSource> e = it.next();
	        	messageHelper.addAttachment( e.getKey(), e.getValue());
	        }
        	
        }
        if( emailEntity.isAuth()) {
	        senderImpl.setUsername( emailEntity.getUsername() ); // 根据自己的情况,设置username  
	        log.info("emailEntity:{}", emailEntity); 
	        senderImpl.setPassword( emailEntity.getPassword()); // 根据自己的情况, 设置password
        }
        
        Properties prop = new Properties();  
        prop.put("mail.smtp.auth", emailEntity.isAuth()); // 将这个参数设为true，让服务器进行认证,认证用户名和密码是否正确  
        prop.put("mail.smtp.timeout", emailEntity.getTimeout() );   
        
        senderImpl.setJavaMailProperties(prop);  
        // 发送邮件  
        
        senderImpl.testConnection();
        
        senderImpl.send(mailMessage);  
        ///senderImpl.send( new EmailMessagePreparator() );
        
        log.info(subject+" 邮件发送成功...");
		
		return true;
    	
    	
    	
    }
    
    @Override
	public boolean sendEmail(String subject, String content,
			List<String> toEmils, List<String> ccEmails,
			List<String> bccEmails, List<String> paths, boolean html) throws MessagingException, UnsupportedEncodingException {
		
		Map<String,InputStreamSource > attachments =Maps.newHashMap();
  
        if( paths != null &&!paths.isEmpty() ) {
        	File file = null;
        	for (String path : paths) {
        		file = new File(path);
        		if( file.exists() ) {
        			attachments.put( file.getName(), new FileSystemResource( file ) );
        			
        		}
        		else {
        			log.warn(file.getAbsolutePath()+" not found.");
        		}
			}
        }
      
		
		return send(subject, content, toEmils, ccEmails, bccEmails, attachments, html); 
	}
    
    @Override
  	public boolean sendEmail(String subject, String content,
  			List<String> toEmils, List<String> ccEmails,
  			List<String> bccEmails, File file, boolean html) throws MessagingException, UnsupportedEncodingException {
  		Map<String,InputStreamSource > attachments =Maps.newHashMap();
          if( null!=file && file.exists() ) {
          	attachments.put( file.getName(), new FileSystemResource( file ) );
          			
          }
        
  		return send(subject, content, toEmils, ccEmails, bccEmails, attachments, html); 
  	}
    @Override
    public boolean sendEmail(String subject, String content,
    		List<String> toEmils, List<String> ccEmails,
    		List<String> bccEmails,Map<String,byte[] > attachmentsByts , boolean html) throws MessagingException, UnsupportedEncodingException {
    	
    	Map<String,InputStreamSource > attachments =Maps.newHashMap();
    	
    	if( attachmentsByts != null &&!attachmentsByts.isEmpty() ) {
    	        Iterator<Entry<String, byte[]>> it = attachmentsByts.entrySet().iterator();
    	        while (it.hasNext()){
    	        	Entry<String, byte[]> e = it.next();
    	        	attachments.put( e.getKey(),new ByteArrayResource(  e.getValue()));
    	        }
            }
    	return send(subject, content, toEmils, ccEmails, bccEmails, attachments, html); 
    }

	@Override
	public boolean sendEmail(String subject, String content,
			List<String> toEmils, List<String> ccEmails, List<String> paths) throws MessagingException, UnsupportedEncodingException {
		// TODO Auto-generated method stub
		return sendEmail(subject, content, toEmils, ccEmails, null, paths,true);
	}

	@Override
	public boolean sendEmail(String subject, String content,
			List<String> toEmils, List<String> paths) throws MessagingException, UnsupportedEncodingException {
		
		return this.sendEmail(subject, content, toEmils, null, null, paths,true);
	}

	@Override
	public boolean sendEmail(String subject, String content, List<String> toEmils) throws MessagingException, UnsupportedEncodingException {
		// TODO Auto-generated method stub
		return this.sendEmail(subject, content, toEmils, null, null, Lists.newArrayList(),true);
	}

	

	public static String getCharset() {
		return charset;
	}

	public static void setCharset(String charset) {
		EmailServiceImpl.charset = charset;
	}

	public EmailEntity getEmailEntity() {
		return emailEntity;
	}

	@Override
	public void setEmailEntity(EmailEntity emailEntity) {
		this.emailEntity = emailEntity;
	}


}
